import pandas as pd
from copy import deepcopy
"""
bi_bybar：
使用bar,数据可以计算在数据流程，最新的数据放在数据流中；out信息：fx,当前笔信息，前一笔涨的信息，前一笔跌的信息；前N笔信息
笔的信息：fx,open,close,high,low,bars_num,bi_timekey:opentimekey,closetimekey,hightimekey,lowtimekey
对于bi的分析 应该使用其他算子 在此统计
重型算子 不建议放在计算图中
复杂笔  存储了笔的压缩历史数据
上涨笔，下跌笔  方向，当前笔；确认上涨  确认下跌  比较复杂 要确认后才会处理；且可以用过其他信息连接在一起
"""
class kline_bi:#满足工作笔数就触发;确认了涨跌确认标识
    def __init__(self,bikey,obj,highkey="high",lowkey="low",bars_len=2):
        obj=obj
        self.bikey=bikey#区别比的关键字，-2,2的转折点信号
        self.fx=None
        self.bar={}
        self.bars = []
        self.bars_len = bars_len
        self.highkey=highkey
        self.lowkey=lowkey
        self.ondata = self.onbar
        self.onbarcall = []
    def setonbar(self,call):
        self.onbarcall.append(call)
    def init_new_bibar(self,b,fx):
        self.bar = {"obj":self.obj,"open": b["open"], "close": b["close"], "low": b["low"], "high": b["high"], "timekey": b["timekey"],
                    "opentimekey": b["timekey"], "lowtimekey": b["timekey"], "hightimekey": b["timekey"], "barsn": 1}
        if fx>=1:
            self.bar["fx"]=1
        else:
            self.bar["fx"]=-1
    def next_new_bibar(self,b,fx):
        self.bar=deepcopy(self.bar)
        t={"obj":self.obj,"open": b["open"], "close": b["close"], "high": b["high"], "timekey": b["timekey"],
                    "opentimekey": b["timekey"],"hightimekey": b["timekey"], "barsn": 1}
        self.bar.update(t)
        if fx >= 1:
            self.bar["fx"] = 1
        else:
            self.bar["fx"] = -1
    def onbar(self,b,tradeday):
        # if "obj" in b.keys():
        #     self.obj=b["obj"]
        fx=b[self.bikey]
        if self.bar:
            if fx==1:
                if self.fx==2:
                    self.next_new_bibar(b,fx)
                else:
                    if b[self.highkey]>self.bar["high"]:
                        if "hightimekey" in b.keys():
                            htk = b["hightimekey"]
                        else:
                            htk=b["timekey"]
                        t = {"high": b[self.highkey], "hightimekey": htk}
                        self.bar.update(t)
                    self.bar["close"]=b["close"]
                    if "closetimekey" in b.keys():
                        htk = b["closetimekey"]
                    else:
                        htk = b["timekey"]
                    self.bar["closetimekey"] = htk
                    self.bar["barsn"]=self.bar["barsn"]+1
                    self.bar["fx"]=1
            elif fx==-1:
                if self.fx==-2:
                    self.next_new_bibar(b,fx)
                else:
                    if b["low"]<self.bar["low"]:
                        if "lowtimekey" in b.keys():
                            htk = b["lowtimekey"]
                        else:
                            htk=b["timekey"]
                        t = {"low": b["low"], "lowtimekey": htk}
                        self.bar.update(t)
                    self.bar["close"]=b["close"]
                    if "closetimekey" in b.keys():
                        htk = b["closetimekey"]
                    else:
                        htk = b["timekey"]
                    self.bar["closetimekey"] = htk
                    self.bar["barsn"]=self.bar["barsn"]+1
                    self.bar["fx"]=-1
            elif fx==-2:#死叉
                if b[self.highkey] > self.bar["high"]:
                    if "hightimekey" in b.keys():
                        htk = b["hightimekey"]
                    else:
                        htk = b["timekey"]
                    t = {"high": b[self.highkey], "hightimekey": htk}
                    self.bar.update(t)
                self.bar["close"] = b["close"]
                if "closetimekey" in b.keys():
                    htk = b["closetimekey"]
                else:
                    htk = b["timekey"]
                self.bar["closetimekey"] = htk
                self.bar["barsn"] = self.bar["barsn"] + 1
                self.bar["fx"] = 1
                for i in self.onbarcall:
                    i(self.bar,tradeday)
                self.bars.append(self.bar)
                if len(self.bars) > self.bars_len:
                    self.bars.pop(0)
            elif fx==2:#金叉
                if b["low"] < self.bar["low"]:
                    if "lowtimekey" in b.keys():
                        htk = b["lowtimekey"]
                    else:
                        htk = b["timekey"]
                    t = {"low": b["low"], "lowtimekey": htk}
                    self.bar.update(t)
                self.bar["close"] = b["close"]
                if "closetimekey" in b.keys():
                    htk = b["closetimekey"]
                else:
                    htk = b["timekey"]
                self.bar["closetimekey"] = htk
                self.bar["barsn"] = self.bar["barsn"] + 1
                self.bar["fx"] = -1
                for i in self.onbarcall:
                    i(self.bar,tradeday)
                self.bars.append(self.bar)
                if len(self.bars) > self.bars_len:
                    self.bars.pop(0)
        else:
            self.init_new_bibar(b,fx)
        return self.bar